﻿#include "formprinter.h"
#include "ui_formprinter.h"
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#include <QTextStream>
#include <QAbstractItemView>
#include <QDirIterator>
#include <QTimer>
#include <QFileDialog>
#include <QDesktopServices>
#include <workorder.h>
#include <QMenu>
#include <MyPrinterFun.h>
#include "myprocess.h"
#include "mainwindow.h"
#include "excel.hpp"

FormPrinter::FormPrinter(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormPrinter)
{
    ui->setupUi(this);

    connect(ui->tableView, &QTableView::customContextMenuRequested
            , this, &FormPrinter::on_tableViewCustomContextMenuRequested);
    // 其他进程
    runexe = new MyProcess(this);
    connect(runexe,SIGNAL(finished(int,QProcess::ExitStatus)),SLOT(finished(int,QProcess::ExitStatus)));
    // 工单号数据操作
    workOrder = new WorkOrder;
    // 全局搜索窗口
    searchForm = new FormAdvancedSearch;
    connect(searchForm, &FormAdvancedSearch::slot_switch_combox, this, &FormPrinter::slot_switch_combox);
    // 读取配置
    ui->checkBox->setChecked(workOrder->getInfor("is_reverse", "./btw").toInt());

    // 更新下拉列表的timer，使用timer防止堵塞
    timer_combox=new QTimer(this);
    timer_combox->setSingleShot(1);
    timer_combox->setInterval(1);
    connect(timer_combox, &QTimer::timeout, this, [=]{
        QString filter;
        if(!ui->lineEdit->text().isEmpty()) filter=ui->lineEdit->text();
        // 获取工单号列表
        QStringList str_list=workOrder->getWorkList();
        // 删除多余的
        for (int i = ui->comboBox->count() - 1; i >= 0; --i) {
            QString itemText = ui->comboBox->itemText(i);
            if (!str_list.contains(itemText)) {
                ui->comboBox->removeItem(i);
            }
        }
        // 添加新增加的
        for (int i = 0; i < str_list.size(); i++) {
            if (-1==ui->comboBox->findText(str_list[i])) {
                ui->comboBox->insertItem(0, str_list[i]);
            }
        }
        // 过滤
        if(filter.isEmpty()) return;
        for (int i = ui->comboBox->count() - 1; i >= 0; --i) {
            QString itemText = ui->comboBox->itemText(i);
            if (-1==itemText.indexOf(filter)) {
                ui->comboBox->removeItem(i);
            }
        }
        if(0==ui->comboBox->count()){
            ui->tableView->standItemModel->clear();
        }
    });
}

// 打开工单号sn文件
void FormPrinter::InitTableData(QString filePath){
    // 获取数据
    QVector<QStringList> all_str_list=workOrder->getData();
    if(all_str_list.empty()) return;
    // 获取和设置已打印的数据行
    QSet<int> printed_rows = workOrder->getLog("log1.dat");
    ui->tableView->delegate->clearGreenRows();
    ui->tableView->delegate->addGreenRows(printed_rows);
    // 添加到表格中
    ui->tableView->setDatas(all_str_list);
    // 生成导出首次使用的默认数据库文件
    if( ui->tableView->standItemModel->rowCount()>0){
        ui->tableView->selectionModel()->select(ui->tableView->standItemModel->index(0,0), QItemSelectionModel::ClearAndSelect);
        ExportData();
        ui->tableView->selectionModel()->select(ui->tableView->standItemModel->index(0,0), QItemSelectionModel::Deselect);
    }
    printTbText(ui->tableView->standItemModel->rowCount(), ui->tableView->standItemModel->rowCount());
}

FormPrinter::~FormPrinter()
{
    delete ui;
}

// 滚动到指定行
void FormPrinter::on_spinBox_valueChanged(int arg1)
{
    arg1--;
    ui->tableView->scrollToRow(arg1);
}

// 导出数据
int FormPrinter::ExportData(bool isSaveLog, bool isGetNoneSelected, bool isGetHiddened){
    QStringList v_headers;
    QVector<QStringList> v_data;
    QString str_log;
    // 先保存字段
    ui->tableView->getHeaders(v_headers);
    // 获取数据
    if(-1==ui->tableView->getDatas(v_data, isSaveLog, isGetNoneSelected, isGetHiddened)) return 0;
    if(v_data.empty()) {
        QMessageBox::warning(this, "错误", "未选中任意行!");
        return 0;
    }
    // 导出数据，保存打印日志
    str_log=data2QString(v_data);
    if(ui->checkBox->isChecked()) std::reverse(v_data.begin(), v_data.end()); // 逆序
    v_data.push_front(v_headers);
    if(0==data_method){
        saveXLS("./btw/"+ui->comboBox->currentText()+"/1.xls", v_data);
        QFile::remove("./btw/"+ui->comboBox->currentText()+"/1.txt");
    }
    else{
        saveCSV("./btw/"+ui->comboBox->currentText()+"/1.txt", v_data);
        QFile::remove("./btw/"+ui->comboBox->currentText()+"/1.xls");
    }
    if(isSaveLog){
        MainWindow::log(ui->comboBox->currentText()+":"+str_log);
        workOrder->log("log1.dat", ui->tableView->delegate->getGreenRows());    // 保存打印记录,标记颜色用
    }
    return v_data.size();
}

// 设置保存数据的方式和打印的方式
void FormPrinter::setDataMethod(int val)
{
    data_method=val;
    workOrder->setInfor("data_method", QString::number(val));
}
void FormPrinter::setPrintMethod(int val)
{
    print_method=val;
    workOrder->setInfor("print_method", QString::number(val));
}

MyTableView *FormPrinter::getTableView()
{
    return ui->tableView;
}

// 打印选中
void FormPrinter::on_pushButton_clicked()
{
    HWND hWnd=myPrinterFun.bartendGetMainWin();
    if(getPrintMethod()==0){
        if(!QFile::exists(bartend_exe)){
            QMessageBox::warning(this, "错误", "未找到打印程序(bartender),请在\"菜单\"中设置.");
            return;
        }
        // 有bartender后台,关闭后才能继续
        if(hWnd){
            QMessageBox::warning(this, "错误", "打印程序(Bartender)在前台,请关闭后才能继续.");
            ShowWindow(hWnd, SW_RESTORE);
            SetForegroundWindow(hWnd);
            return;
        }
    }else{
        if(!QFile::exists(bylabel_exe)){
            QMessageBox::warning(this, "错误", "未找到打印程序(bartender),请在\"菜单\"中设置.");
            return;
        }
    }
    if(IsWindowVisible(myPrinterFun.bylGetMainWin(ui->comboBox->currentText()+"/1"))||QProcess::Running==runexe->state()){
        if(getPrintMethod()==0){
            if(QMessageBox::Yes==QMessageBox::warning(this, "错误", "后台程序正在运行,是否强制结束并打印?", QMessageBox::Yes|QMessageBox::No)){
                runexe->kill();
                runexe->waitForFinished(100);
            }else{
                return;
            }
        }else{
            runexe->kill();
            runexe->waitForFinished(100);
        }
    }
    int printNum=ExportData(1);
    if(printNum<2) return;
    if(0==getPrintMethod()){    // 调用bartender进行打印
        QStringList arguments;
        arguments << "/F="+QDir::toNativeSeparators("./btw/"+ui->comboBox->currentText()+"/1.btw") << (ui->checkBox_2->isChecked()?"/FPD":"/P") << "/X";
        runexe->start(bartend_exe, arguments);
        MainWindow::static_text(QString("铭牌条码(bartender)打印调用成功,总数:%1").arg(printNum-1));
        runexe->ExitMsg("调用bartender打印铭牌条码打印调用结束1!", "调用bartender打印铭牌条码打印调用结束2!");
    }else{                      // //调用bylabel进行打印
        // 打开bylabel贴纸
        HWND beforHwnd=GetForegroundWindow();
        on_pushButton_3_clicked();
        QTimer *timer = new QTimer(this);
        timer->setInterval(100);
        connect(timer, &QTimer::timeout, this, [=](){
            HWND hWnd=myPrinterFun.bylGetMainWin(ui->comboBox->currentText()+"/1");
            if(NULL!=hWnd){
                // MoveWindow(hWnd, 0, 0, 100, 100, 0); // 会导致bylabel打印的条码上下偏位问题
                Sleep(1000);
                ShowWindow(hWnd, SW_HIDE);
                timer->stop();
                Sleep(1000);
                MyPrinterFun myPrinterFun;
                HWND main_print_win = myPrinterFun.bylGetPrinterWindow();
                if(NULL==main_print_win){
                    // 发送键值Ctrl+P
                    SetForegroundWindow(hWnd);
                    keybd_event(VK_CONTROL, 0, 0, 0);
                    Sleep(10);
                    keybd_event('P', 0, 0, 0);
                    Sleep(10);
                    keybd_event('P', 0, KEYEVENTF_KEYUP, 0);
                    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
                    Sleep(500);
                    main_print_win = myPrinterFun.bylGetPrinterWindow();
                }
                QList<HWND> list_hwnd=myPrinterFun.bylGetPrinterWindowNum(main_print_win);
                //设置参数起始标签，打印标签数量，相同标签打印数量
                if(list_hwnd.size()==3){
                    SendMessageW(list_hwnd[0], WM_SETTEXT, 0, (LPARAM)L"1"); //起始标签
                    SendMessageW(list_hwnd[1], WM_SETTEXT, 0, (LPARAM)QString::number(printNum-1).toStdWString().c_str()); //打印标签数量
                    SendMessageW(list_hwnd[2], WM_SETTEXT, 0, (LPARAM)L"1"); //相同标签打印数量
                    // 调用打印按钮
                    Sleep(10);
                    HWND hwnd_OK = myPrinterFun.bylGetPrinterWindowOK(main_print_win);
                    SendMessage(hwnd_OK, BM_CLICK, 0, 0);
                    MainWindow::static_text(QString("铭牌条码(byl)打印调用成功,总数:%1").arg(printNum-1));
                }else{
                    MainWindow::static_text(QString("铭牌条码(byl)打印调用失败(未找到:起始标签，打印标签数量，相同标签打印数量)!"));
                }
                SetForegroundWindow(beforHwnd);
                timer->deleteLater();
            }
        });
        timer->start();
    }
    ui->tableView->setFocus();
}

// 更新工单号选项
void FormPrinter::updateCombox()
{
    timer_combox->stop();
    timer_combox->start();
}

// 手动切到工单号sn文件
void FormPrinter::switchCombox(QString filePath){
    filePath.replace("./btw/", "");
    filePath.replace("/print_all_data.txt", "");
    QTimer::singleShot(100, this, [=](){
        ui->comboBox->setCurrentText(filePath);
        InitTableData(filePath);
    });
}

// 工单号下拉列表变动槽
void FormPrinter::on_comboBox_currentTextChanged(const QString &arg1)
{
    if(arg1.isEmpty()||combo_sub==arg1) return;
    workOrder->setWorkPath(arg1);
    ui->lineEdit_2->setText("");
    data_method=workOrder->getInfor("data_method").toInt();
    print_method=workOrder->getInfor("print_method").toInt();
    emit slot_reset_export_data_method(data_method);
    emit slot_reset_print_method(print_method);
    InitTableData(arg1);
    combo_sub=arg1;
}

// 过滤工单号（太慢，换回车过滤）
void FormPrinter::on_lineEdit_textChanged(const QString &arg1)
{
    //updateCombox();
}

// 打开btw
void FormPrinter::on_pushButton_3_clicked()
{
    if(0==getPrintMethod()){
        // 有bartender后台,关闭后才能继续
        HWND hWnd=FindWindowW(L"BartendWindowClass", NULL);
        wchar_t windowTitle[256] = {0};
        int length = GetWindowTextW(hWnd, windowTitle, sizeof(windowTitle) / sizeof(windowTitle[0]));
        if(length>0&&-1!=QString::fromStdWString(windowTitle).indexOf(".btw")){
            QMessageBox::warning(this, "错误", "打印程序(bartender)在前台, 请关闭后才能继续.");
            ShowWindow(hWnd, SW_RESTORE);
            SetForegroundWindow(hWnd);
            return;
        }
        QStringList arguments;
        arguments << "/F="+QDir::toNativeSeparators(QDir("./btw/"+ui->comboBox->currentText()).absolutePath()+"/1.btw");
        runexe->start(bartend_exe, arguments);
    }else{
        QStringList arguments;
        arguments << QDir("./btw/"+ui->comboBox->currentText()).absolutePath()+"/1.byl";
        runexe->start(bylabel_exe, arguments);
    }
}

// 打开工单号路径
void FormPrinter::on_pushButton_2_clicked()
{
    QDesktopServices::openUrl(QUrl("file:///"+QDir("./btw/"+ui->comboBox->currentText()).absolutePath()));
}

// 进程结束
void FormPrinter::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
    if(exitCode==0){
        if(!runexe->myprocess_msg_sucess.isEmpty()){
            QMessageBox::information(this, "执行完毕-"+QString::number(exitCode), runexe->myprocess_msg_sucess);
            runexe->myprocess_msg_sucess="";
        }
    }else{
        if(!runexe->myprocess_msg_failed.isEmpty()){
            QMessageBox::warning(this, "执行完毕-"+QString::number(exitCode), runexe->myprocess_msg_failed);
            runexe->myprocess_msg_failed="";
        }
    }
}

// 保存配置-是否逆序打印
void FormPrinter::on_checkBox_stateChanged(int arg1)
{
    //setInfor("is_reverse", QString::number(arg1));
    workOrder->setInfor("is_reverse", QString::number(arg1), "./btw");
}

// 全局搜索的槽
void FormPrinter::slot_switch_combox(QString filter, QString data)
{
    ui->comboBox->setCurrentText(filter);
    ui->lineEdit_2->setText(data);
}

// 全局搜索
void FormPrinter::SearchAll(){
    searchForm->activateWindow();
    searchForm->show();
}

// 列表数据过滤
void FormPrinter::on_lineEdit_2_textChanged(const QString &arg1)
{
    ui->tableView->setUpdatesEnabled(0);
    int not_hidden_num=ui->tableView->standItemModel->rowCount();
    if(arg1.count("-")==1){
        QStringList strList=arg1.split("-");
        do{
            if(strList.size()!=2) break;
            int minNum=strList[0].toInt(), maxNum=strList[1].toInt();
            for (int r=0; r<ui->tableView->standItemModel->rowCount(); r++) {
                bool isHide=(minNum<=r+1&&r+1<=maxNum&&minNum!=0&&maxNum!=0)?0:1;
                if(isHide) not_hidden_num--;
                ui->tableView->setRowHidden(r, isHide);
            }
        }while(0);
        ui->tableView->verticalHeader()->setMinimumWidth(0);
        ui->tableView->verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
        ui->tableView->update();
        QCoreApplication::processEvents();
        ui->tableView->verticalHeader()->setMinimumWidth(ui->tableView->verticalHeader()->width()+10);
    }
    else{
        QStringList strList=arg1.split("|");
        for (int r=0; r<ui->tableView->standItemModel->rowCount(); r++) {
            bool isHide=1;
            if(arg1.isEmpty()){
                isHide=0;
            }else{
                for (int c=0; c<ui->tableView->standItemModel->columnCount(); c++) {
                    foreach (auto str, strList) {
                        if(-1!=ui->tableView->standItemModel->item(r,c)->text().indexOf(str)){
                            isHide=0;
                            break;
                        }
                    }
                }
            }
            if(isHide) not_hidden_num--;
            ui->tableView->setRowHidden(r, isHide);
        }
    }
    printTbText(ui->tableView->standItemModel->rowCount(), not_hidden_num);
    ui->tableView->setUpdatesEnabled(1);
}

// 列表右键
void FormPrinter::on_tableViewCustomContextMenuRequested(const QPoint &pos)
{
    Q_UNUSED(pos);
    QMenu menu;
    //添加右键菜单的选项
    menu.addAction("导出选中");
    menu.addAction("跳转到未打印行");
    connect(&menu, &QMenu::triggered, [=](QAction *action){
        if("导出选中"==action->text()){
            if(ExportData()>1) QMessageBox::information(this, "导出成功", "已导出数据至1.xls/1.txt,请编辑1.btw/1.byl打印文件,链接此数据库即可.");
        }else if("跳转到未打印行"==action->text()){
            int rowTmp=-1;
            for (int r=0; r<ui->tableView->standItemModel->rowCount(); r++) {
                if(!ui->tableView->isRowHidden(r)&&!ui->tableView->delegate->isRowGreen(r)){
                    rowTmp=r;
                    break;
                }
            }
            if(rowTmp!=-1){
                on_spinBox_valueChanged(rowTmp+1);
            }
        }
    });
    // 显示menu菜单并设置其显示位置为鼠标位置
    menu.exec(QCursor::pos());
}

void FormPrinter::keyPressEvent(QKeyEvent *event){
    // 按下了Ctrl+P
    if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_P) {
        on_pushButton_clicked();
        event->accept();
    } else {
        QWidget::keyPressEvent(event);
    }
}

// 输出table的总行和显示行
void FormPrinter::printTbText(int all_rows, int not_hidden_rows){
    ui->label->setText(QString("总行：%1，显示行：%2.").arg(all_rows).arg(not_hidden_rows));
}


void FormPrinter::on_lineEdit_returnPressed()
{
    updateCombox();
}

